package com.cc.bsp.persistence.hibernate.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.cc.bsp.persistence.IOrder;
import com.cc.bsp.persistence.IPage;
import com.cc.bsp.persistence.IQueryPageOrder;
import com.cc.bsp.persistence.entity.IEntity;
import com.cc.bsp.persistence.exception.PersistenceException;
import com.cc.bsp.persistence.hibernate.IHRootDao;
import com.cc.bsp.persistence.hibernate.IHXQLDao;
import com.cc.bsp.persistence.hibernate.expand.namedql.template.StatementTemplate;
import com.cc.bsp.persistence.util.BeansUtil;

public class BasicXQLDaoImpl<T extends IEntity,ID extends Serializable> extends HibernateDaoSupport implements IHXQLDao {
	
	public StatementTemplate statementTemplate;

	@SuppressWarnings("unchecked")
	public <X> X findUniqueByHQL(String hql, Object... propertyParameters) throws PersistenceException {
		   return (X) createHQLQuery(hql, null, propertyParameters).uniqueResult();  
	}

	@SuppressWarnings("unchecked")
	public <X> X findUniqueBySQL(String sql, Object... propertyParameters) throws PersistenceException {
		  return (X) createSQLQuery(sql, null, propertyParameters).uniqueResult(); 
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findByHQL(String hql, Object... propertyParameters) throws PersistenceException {

		return createHQLQuery(hql, null, propertyParameters).list();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findBySQL(String sql, Object... propertyParameters) throws PersistenceException {
		
		return createSQLQuery(sql, null, propertyParameters).list();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findByNamedQL(String namedQL, final IHRootDao.TYPE type, Object... javaBeans)
			throws PersistenceException {

		Map<String, Object> parameters = BeansUtil.beans2Map(javaBeans);
	
		if(IHRootDao.TYPE.HQL==type){
			String ql = statementTemplate.getHQL(namedQL,parameters);
			return createHQLQuery(ql, null,parameters).list();
		}else if(IHRootDao.TYPE.SQL==type){
			String ql = statementTemplate.getSQL(namedQL,parameters);
			return createSQLQuery(ql, null,parameters).list();
		}

		return null;
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findByNamedQL(String namedQL,final IHRootDao.TYPE type,  Map<String, ?> parameters)
			throws PersistenceException {
		if(IHRootDao.TYPE.HQL==type){
			String ql = statementTemplate.getHQL(namedQL,parameters);
			return createHQLQuery(ql, null,parameters).list();
		}else if(IHRootDao.TYPE.SQL==type){
			String ql = statementTemplate.getSQL(namedQL,parameters);
			return createSQLQuery(ql, null,parameters).list();
		}
		return null;
	}

	public void batchExecuteHQL(String hql, Object... propertyParameters)throws PersistenceException {
		 createHQLQuery(hql, null, propertyParameters).executeUpdate(); 
		
	}

	public void batchExecuteSQL(String sql, Object... propertyParameters)throws PersistenceException {
		 createSQLQuery(sql, null, propertyParameters).executeUpdate(); 
	}

	public void batchExecuteHQL(String hql, Map<String, ?> parameters)throws PersistenceException {
		 createSQLQuery(hql,  null,parameters).executeUpdate(); 
		
	}

	public void batchExecuteSQL(String sql, Map<String, ?> parameters) throws PersistenceException {
		 createSQLQuery(sql, null,parameters).executeUpdate(); 
		
	}
	
	@SuppressWarnings("unchecked")
	public <X> List<X> findByHQL(String hql, IQueryPageOrder pageorder,
			Object... propertyParameters) throws PersistenceException {
		return createHQLQuery(hql, pageorder, propertyParameters).list();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findBySQL(String sql, IQueryPageOrder pageorder,
			Object... propertyParameters) throws PersistenceException {
		return createSQLQuery(sql, pageorder, propertyParameters).list();
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findByNamedQL(String namedQL, IHRootDao.TYPE type,
			IQueryPageOrder pageorder, Object... javaBeans) throws PersistenceException {
		Map<String, Object> parameters = BeansUtil.beans2Map(javaBeans);
		if(IHRootDao.TYPE.HQL==type){
			String ql = statementTemplate.getHQL(namedQL,parameters);
			return createHQLQuery(ql, pageorder,parameters).list();
		}else if(IHRootDao.TYPE.SQL==type){
			String ql = statementTemplate.getSQL(namedQL,parameters);
			return createSQLQuery(ql, pageorder,parameters).list();
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public <X> List<X> findByNamedQL(String namedQL, IHRootDao.TYPE type,
			IQueryPageOrder pageorder, Map<String, ?> parameters)
			throws PersistenceException {
		if(IHRootDao.TYPE.HQL==type){
			String ql = statementTemplate.getHQL(namedQL,parameters);
			return createHQLQuery(ql, pageorder,parameters).list();
		}else if(IHRootDao.TYPE.SQL==type){
			String ql = statementTemplate.getSQL(namedQL,parameters);
			return createSQLQuery(ql, pageorder,parameters).list();
		}
		return null;
	}
	

	Query createHQLQuery(final String queryString,IQueryPageOrder pageorder,final Object... propertyParameters) {

		Query query = createQueryXQLQuery(queryString,pageorder);
		
		if (propertyParameters != null) {
			for (int i = 0; i < propertyParameters.length; i++) {
				query.setParameter(i, propertyParameters[i]);
			}
		}
		return query;
	}
	

	Query createHQLQuery(final String queryString,IQueryPageOrder pageorder,final Map<String, ?> parameters) {
		Query query = createQueryXQLQuery(queryString,pageorder);
		query.setProperties(parameters);
		return query;
	}
	
	Query createSQLQuery(final String queryString,IQueryPageOrder pageorder,final Object... propertyParameters) {
		Query query = createQueryXQLQuery(queryString,pageorder);
		if (propertyParameters != null) {
			for (int i = 0; i < propertyParameters.length; i++) {
				query.setParameter(i, propertyParameters[i]);
			}
		}
		return query;
	}
	

	Query createSQLQuery(final String queryString,IQueryPageOrder pageorder,final Map<String, ?> parameters) {
		Query query = createQueryXQLQuery(queryString,pageorder);
		query.setProperties(parameters);
		return query;
	}

	Query createQueryXQLQuery(final String queryString,IQueryPageOrder pageorder) {
		IOrder order = null;
		IPage page = null;

		String finalQueryString = null;

		if (pageorder != null) {
			order = pageorder.getOrder();
			page = pageorder.getPage();
		}

		if (order != null) {
			String orderSQL = order.getOrderSQL();
			finalQueryString = queryString + " " + orderSQL;
		} else {
			finalQueryString = queryString;
		}

		Query query = getSession().createQuery(finalQueryString);

		if (page != null) {
			query.setFirstResult(page.getCurrentBeginRow());
			query.setMaxResults(page.getCurrentEndRow());
		}
		return query;
	}
	
	protected StatementTemplate getStatementTemplate() {
		return statementTemplate;
	}

	protected void setStatementTemplate(StatementTemplate statementTemplate) {
		this.statementTemplate = statementTemplate;
	}



	

}
